﻿#include "networkManager.h"

#include "curl/curlDownload.h"
#include "curl/curlUpload.h"
#include "stream/hnstream.h"
#include <iostream>
#include <iomanip>
#include <thread>
#include "time/hntime.h"


// 定义全局变量
namespace HNNetwork {

    int MultiTaskDownload(std::vector<UrlObeject*>& urlObjects, long flowSize) 
    {
#ifdef ENABLE_OPEN_SSL
        SSL_library_init();
        OpenSSL_add_all_algorithms();
        SSL_load_error_strings();
        ERR_load_BIO_strings();
        ERR_load_crypto_strings();
#endif
        // 初始化libcurl
        CURLcode res = CURLE_OK;
        res = curl_global_init(CURL_GLOBAL_DEFAULT);
        if (res != CURLE_OK)
        {
            std::cerr << "Failed to initialize libcurl." << std::endl;
            return false;
        }
        long sum = 0;
        if (getDownloadSize(urlObjects,sum))
        {
            std::cout << std::setprecision(2) << "总计：" << urlObjects.size() << " 个，" << convertDataSize(sum) << std::endl;
            if (sum <= 0) 
            {
                std::cout << "文件总大小为 0 MB，未知文件大小，停止下载！" << std::endl;
                return false;
            }
            // todo 交互提示文件大小是否继续下载
            int index = 0;
            HNTimer allTimer;
            std::vector<UrlObeject*>::iterator iter = urlObjects.begin();
            for (; iter != urlObjects.end(); ++iter)
            {
                index++;
                HNTimer tmpTimer;
                std::cout << "开始第 " << std::to_string(index) << "任务，" << (*iter)->url << "," << convertDataSize( (*iter)->size ) << std::endl;
                if ((*iter)->size <= 0)
                {
                    std::cout << "第 " << std::to_string(index) << "任务文件总大小为 0 MB，跳过文件下载" << std::endl;
                    continue;
                }
                downloadFile(*iter, flowSize);
                std::cout << "完成第 " << std::to_string(index)<< "任务，"<< (*iter)->url<<","<< convertDataSize((*iter)->size) 
                   <<", 耗时：" << tmpTimer.getCoastTime() << " 速率：" << getNetworkRate((*iter)->size, tmpTimer.getCoastTime_ms()) << std::endl;
            }
            std::cout << "下载完成，总耗时：" << allTimer.getCoastTime() <<" 速率："<< getNetworkRate(sum, allTimer.getCoastTime_ms()) << std::endl;
        }

        // 清理libcurl资源
        curl_global_cleanup();
        return true;
    }

    // 主函数，负责初始化、启动线程并监控上传进度
    int TaskUpload(const char* url, const char* filePath)
    {
        uploadFile.open(filePath, std::ios::binary); // 打开待上传的文件
        if (!uploadFile.is_open())
        {
            std::cout << "Failed to open file!" << std::endl;
            return -1;
        }

        long fileSize = getFileSize(uploadFile); // 获取文件总大小
        long uploadedSize = getUploadSize(url); // 获取已上传的文件大小
        long chunkNum = (fileSize - uploadedSize + CHUNK_SIZE - 1) / CHUNK_SIZE; // 计算需要分块的数量
        std::vector<std::thread> threads; // 存储线程对象的容器
        // 创建多个线程，每个线程负责上传一个数据块
        for (int i = 0; i < THREAD_NUM && i < chunkNum; ++i)
        {
            long start = i * CHUNK_SIZE;
            long end = (i == chunkNum - 1) ? fileSize : start + CHUNK_SIZE - 1;
            std::thread t(uploadChunk, fileSize, url, start, end, i);
            threads.push_back(std::move(t));
        }

        while (uploadedSize < fileSize)
        {
            std::this_thread::sleep_for(std::chrono::seconds(1)); // 每隔一秒钟检查一次进度
            for (int i = 0; i < THREAD_NUM && i < chunkNum; ++i)
            {
                std::ifstream logFile("log" + std::to_string(i) + ".txt");

                if (logFile.is_open())
                {
                    std::string line;
                    while (std::getline(logFile, line))
                    {
                        if (line.find("upload success") != std::string::npos)
                        {
                            uploadedSize += CHUNK_SIZE;
                            break;
                        }
                        else if (line.find("upload failed") != std::string::npos)
                        {
                            // 处理上传失败的情况
                            // ...
                        }
                    }
                    logFile.close();
                }
            }
        }
        for (auto& t : threads)
        {
            t.join(); // 等待所有线程结束
        }
        uploadFile.close();
        return 0;
    }
}//HNNetWork
